from sqlalchemy.orm import Session
from fastapi import HTTPException, status
from datetime import timedelta
from app.database.models.user import User
from app.schemas.user import UserCreate, UserLogin
from app.utils.security import verify_password, get_password_hash, create_access_token
from app.utils.redis import redis_client
from app.config import settings

class AuthService:
    """认证服务类"""
    
    @staticmethod
    def register_user(db: Session, user_in: UserCreate) -> User:
        """注册新用户"""
        # 检查用户名是否已存在
        db_user = db.query(User).filter(User.username == user_in.username).first()
        if db_user:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="用户名已存在"
            )
        
        # 检查邮箱是否已存在
        db_user = db.query(User).filter(User.email == user_in.email).first()
        if db_user:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="邮箱已被注册"
            )
        
        # 创建新用户
        db_user = User(
            username=user_in.username,
            email=user_in.email,
            hashed_password=get_password_hash(user_in.password),
            full_name=user_in.full_name
        )
        
        # 保存到数据库
        db.add(db_user)
        db.commit()
        db.refresh(db_user)
        return db_user
    
    @staticmethod
    def login_user(db: Session, user_in: UserLogin) -> str:
        """用户登录并返回令牌"""
        # 查询用户
        user = db.query(User).filter(User.username == user_in.username).first()
        
        # 验证用户是否存在且密码正确
        if not user or not verify_password(user_in.password, user.hashed_password):
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="用户名或密码错误"
            )
        
        # 验证用户是否活跃
        if not user.is_active:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="用户已被禁用"
            )
        
        # 创建访问令牌
        access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        access_token = create_access_token(
            user.id, expires_delta=access_token_expires
        )
        
        # 将令牌存储到Redis，便于后续验证和注销
        redis_key = f"token:{user.id}"
        redis_client.set(
            redis_key, 
            access_token, 
            expire_seconds=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60
        )
        
        return access_token
    
    @staticmethod
    def logout_user(user_id: int) -> bool:
        """用户登出，删除Redis中的令牌"""
        redis_key = f"token:{user_id}"
        return redis_client.delete(redis_key) > 0
    
    @staticmethod
    def get_current_user(db: Session, user_id: int) -> User:
        """获取当前登录用户"""
        user = db.query(User).filter(User.id == user_id).first()
        if not user:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="用户不存在"
            )
        if not user.is_active:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="用户已被禁用"
            )
        return user
    
    @staticmethod
    def verify_token(user_id: int, token: str) -> bool:
        """验证令牌是否有效"""
        redis_key = f"token:{user_id}"
        stored_token = redis_client.get(redis_key)
        return stored_token == token
